package com.splic.product.service.impl;

import com.github.pagehelper.Page;
import com.splic.common.exception.BusinessException;
import com.splic.common.utils.DateUtils;
import com.splic.common.utils.StringUtils;
import com.splic.product.domain.*;
import com.splic.product.dto.UserSubRecordDto;
import com.splic.product.dto.UserSubRecordResultDto;
import com.splic.product.mapper.UserSubRecordMapper;
import com.splic.product.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户订阅记录Service业务层处理
 * 
 * @author singe
 * @date 2022-01-04
 */
@Service
@Slf4j
public class UserSubRecordServiceImpl implements UserSubRecordService
{
    @Autowired
    private UserSubRecordMapper userSubRecordMapper;
    @Autowired
    private EmailSendCodeService emailSendCodeServiceImpl;
    @Autowired
    private GoodsTypeService goodsTypeServiceImpl;
    @Autowired
    private ProductService productServiceImpl;
    @Autowired
    private UserService userServiceImpl;
    @Autowired
    private DeviceService deviceServiceImpl;

    /**
     * 查询用户订阅记录
     * 
     * @param id 用户订阅记录主键
     * @return 用户订阅记录
     */
    @Override
    public UserSubRecordDto selectUserSubRecordById(Long id)
    {
        return userSubRecordMapper.selectUserSubRecordById(id);
    }

    /**
     * 查询用户订阅记录列表
     * 
     * @param userSubRecordDto 用户订阅记录
     * @return 用户订阅记录
     */
    @Override
    public List<UserSubRecordDto> selectPageList(UserSubRecordDto userSubRecordDto)
    {
        Page<UserSubRecordDto> userSubRecordDtoPage = new Page<>();
        UserSubRecord userSubRecord = new UserSubRecord();
        BeanUtils.copyProperties(userSubRecordDto,userSubRecord);

        if (StringUtils.isNotEmpty(userSubRecordDto.getUserIdentify())){
            User user = userServiceImpl.getByUserIdentify(userSubRecordDto.getUserIdentify());
            if(user != null){
                userSubRecord.setUserId(user.getId());
            }
        }
        if (StringUtils.isNotEmpty(userSubRecordDto.getDeviceIdentify())){
            Device device = deviceServiceImpl.getByDeviceIdentify(userSubRecordDto.getDeviceIdentify());
            if(device != null){
                userSubRecord.setDeviceId(device.getId());
            }
        }

        Page<UserSubRecord> goodsPage = userSubRecordMapper.selectUserSubRecordList(userSubRecord);
        if(CollectionUtils.isNotEmpty(goodsPage)){
            Set<Long> goodsTypeIdSet = goodsPage.stream().map(UserSubRecord::getGoodsTypeId).collect(Collectors.toSet());
            Map<Long,String> goodsTypeMap = null;
            if(CollectionUtils.isNotEmpty(goodsTypeIdSet)){
                List<GoodsType> goodsTypeList = goodsTypeServiceImpl.getByIds(goodsTypeIdSet);
                 if(CollectionUtils.isNotEmpty(goodsTypeList)){
                    goodsTypeMap = goodsTypeList.stream().collect(Collectors.toMap(GoodsType::getId,GoodsType::getName));
                }
            }
            Set<Long> userIdSet = goodsPage.stream().map(UserSubRecord::getUserId).collect(Collectors.toSet());
            Map<Long,String> userMap = null;
            if(CollectionUtils.isNotEmpty(userIdSet)){
                List<User> userList = userServiceImpl.getByIds(userIdSet);
                if(CollectionUtils.isNotEmpty(userList)){
                    userMap = userList.stream().collect(Collectors.toMap(User::getId,User::getUserIdentify));
                }
            }

            Set<Long> deviceIdSet = goodsPage.stream().filter(o -> o.getDeviceId() != null).map(UserSubRecord::getDeviceId).collect(Collectors.toSet());
            Map<Long,String> deviceMap = null;
            if(CollectionUtils.isNotEmpty(deviceIdSet)){
                List<Device> deviceList = deviceServiceImpl.getByIds(deviceIdSet);
                if(CollectionUtils.isNotEmpty(deviceList)){
                    deviceMap = deviceList.stream().collect(Collectors.toMap(Device::getId,Device::getDeviceIdentify));
                }
            }

            UserSubRecordDto dto = null;
            for(UserSubRecord g :goodsPage){
                dto = new UserSubRecordDto();
                BeanUtils.copyProperties(g,dto);
                if(goodsTypeMap!= null){
                    dto.setGoodsTypeName(goodsTypeMap.get(g.getGoodsTypeId()));
                }
                if(userMap!= null){
                    dto.setUserIdentify(userMap.get(g.getUserId()));
                }
                if(deviceMap!= null){
                    dto.setDeviceIdentify(deviceMap.get(g.getDeviceId()));
                }
                userSubRecordDtoPage.add(dto);
            }
        }
        userSubRecordDtoPage.setTotal(goodsPage.getTotal());
        return userSubRecordDtoPage;
    }

    /**
     * 查询用户订阅记录列表
     *
     * @param userSubRecord 用户订阅记录
     * @return 用户订阅记录
     */
    @Override
    public List<UserSubRecord> selectUserSubRecordList(UserSubRecord userSubRecord)
    {
        return userSubRecordMapper.selectUserSubRecordList(userSubRecord);
    }

    /**
     * 新增用户订阅记录
     * 
     * @param userSubRecord 用户订阅记录
     * @return 结果
     */
    @Override
    public int insert(UserSubRecord userSubRecord)
    {
        userSubRecord.setCreateTime(DateUtils.getNowDate());
        return userSubRecordMapper.insert(userSubRecord);
    }

    /**
     * 修改用户订阅记录
     * 
     * @param userSubRecord 用户订阅记录
     * @return 结果
     */
    @Override
    public int update(UserSubRecord userSubRecord)
    {
        userSubRecord.setUpdateTime(DateUtils.getNowDate());
        return userSubRecordMapper.update(userSubRecord);
    }


    /**
     * 删除用户订阅记录信息
     * 
     * @param id 用户订阅记录主键
     * @return 结果
     */
    @Override
    public int deleteById(Long id)
    {
        return userSubRecordMapper.deleteById(id);
    }
    /**
     * 修改用户订阅记录
     *
     * @param userSubRecord 用户订阅记录信息
     * @return 结果
     */
    @Override
    @Transactional
    public int saveOrUpdate(UserSubRecord userSubRecord)
    {
        if(userSubRecord.getId() != null){
            userSubRecord.setUpdateTime(new Date());
            return userSubRecordMapper.update(userSubRecord);
        }else{
            userSubRecord.setCreateTime(new Date());
            return userSubRecordMapper.insert(userSubRecord);
        }
    }

    @Override
    public UserSubRecord selectUserSubRecord(Long userId, Long productId, Long goodsTypeId) {
        UserSubRecord userSubRecord = new UserSubRecord();
        userSubRecord.setUserId(userId);
        userSubRecord.setProductId(productId);
        userSubRecord.setGoodsTypeId(goodsTypeId);
        List<UserSubRecord> userSubRecordList = userSubRecordMapper.selectUserSubRecordList(userSubRecord);
        if(CollectionUtils.isNotEmpty(userSubRecordList)){
            return userSubRecordList.get(0);
        }
        return null;
    }

    @Override
    public List<UserSubRecordResultDto> getUserSubRecordList(Long userId, String packageKey) {
        UserSubRecord userSubRecord = new UserSubRecord();
        userSubRecord.setUserId(userId);
        if(StringUtils.isNotEmpty(packageKey)){
            Product product = productServiceImpl.getByPackageKey(packageKey);
            if (product == null){
                throw new BusinessException("应用查询失败。");
            }
            userSubRecord.setProductId(product.getId());
        }
        List<UserSubRecordResultDto> recordResultDtoList = Lists.newArrayList();
        List<UserSubRecord> userSubRecordList = this.selectUserSubRecordList(userSubRecord);
        if (CollectionUtils.isNotEmpty(userSubRecordList)){
            UserSubRecordResultDto resultDto = null;
            for(UserSubRecord userSub:userSubRecordList){
                resultDto = new UserSubRecordResultDto();
                BeanUtils.copyProperties(userSub,resultDto);
                GoodsType goodsType = goodsTypeServiceImpl.selectGoodsTypeById(userSub.getGoodsTypeId());
                if (goodsType != null){
                    resultDto.setGoodsTypeIcon(goodsType.getIcon());
                    resultDto.setGoodsTypeIntroduction(goodsType.getIntroduction());
                }
                recordResultDtoList.add(resultDto);
            }
        }
        return recordResultDtoList;
    }

    @Override
    public List<UserSubRecord> queryUserSubListByGreaterId(Long offsetId, int limitNum) {
        return userSubRecordMapper.queryUserSubListByGreaterId(offsetId, limitNum);
    }

    @Override
    public void clearUserSubStatusById(Long id) {
        userSubRecordMapper.clearUserSubStatusById(id);
    }

    /**
     * 用户订购记录添加或更新
     *
     * @param userSubRecordDto
     * @param dayNum
     * @param order
     * @param goods
     */
    @Override
    public void updateUserSubInfo(UserSubRecord userSubRecordDto, Integer dayNum, Order order, Goods goods) {
        UserSubRecord userSubRecord = this.selectUserSubRecord(userSubRecordDto.getUserId(),userSubRecordDto.getProductId(),userSubRecordDto.getGoodsTypeId());
        if (userSubRecord != null){
            //判断订阅记录是否 已过期或者日期已被清空
            if(Objects.equals(userSubRecord.getStatus(),1)){
                userSubRecord.setEffictEndTime(DateUtils.addDays(userSubRecord.getEffictEndTime()!=null?userSubRecord.getEffictEndTime():new Date(),dayNum));
            }else{
                userSubRecord.setEffictStartTime(new Date());
                userSubRecord.setEffictEndTime(DateUtils.addDays(userSubRecord.getEffictStartTime(),dayNum));
                userSubRecord.setStatus(1);
            }
            int subCount = this.update(userSubRecord);
            //发送邮件
            User user = userServiceImpl.selectUserById(userSubRecordDto.getUserId());
            if (user != null && StringUtils.isNotEmpty(user.getEmail())) {
                emailSendCodeServiceImpl.sendEmailSubscribe(userSubRecord, user, order, goods.getDesc());
            }
            if(subCount <= 0){
                log.error("订单状态更新失败,用户订阅记录更新失败,订单号:{}",order.getOrderNo());
                return ;
            }
        }else{
            userSubRecord = new UserSubRecord();
            userSubRecord.setUserId(userSubRecordDto.getUserId());
            User user = userServiceImpl.selectUserById(userSubRecordDto.getUserId());
            if(user != null){
                Device device = deviceServiceImpl.selectDeviceByUserId(user.getId());
                if (device == null){
                    log.warn("用户查询设备失败,用户ID:{}",userSubRecordDto.getUserId());
                }else{
                    userSubRecord.setDeviceId(device.getId());
                }
            }
            GoodsType goodsType = goodsTypeServiceImpl.selectGoodsTypeById(userSubRecordDto.getGoodsTypeId());
            if(goodsType != null){
                userSubRecord.setGoodsTypeName(goodsType.getName());
            }
            userSubRecord.setGoodsTypeId(userSubRecordDto.getGoodsTypeId());
            userSubRecord.setProductId(userSubRecordDto.getProductId());
            userSubRecord.setProductName(userSubRecordDto.getProductName());
            userSubRecord.setEffictStartTime(new Date());
            userSubRecord.setEffictEndTime(DateUtils.addDays(userSubRecord.getEffictStartTime(),dayNum));
            userSubRecord.setStatus(1);
            int subCount = this.insert(userSubRecord);

            //发送邮件
            if (user != null && StringUtils.isNotEmpty(user.getEmail())) {
                emailSendCodeServiceImpl.sendEmailSubscribe(userSubRecord, user, order, goods.getDesc());
            }

            if(subCount <= 0){
                log.error("订单状态更新失败,用户订阅记录新增失败,订单号:{}",order.getOrderNo());
                return ;
            }
        }
    }

    @Override
    public void updateUserSubInfoTime(UserSubRecord userSubRecordDto, BigDecimal hour, Order order, Goods goods) {
        UserSubRecord userSubRecord = this.selectUserSubRecord(userSubRecordDto.getUserId(),userSubRecordDto.getProductId(),userSubRecordDto.getGoodsTypeId());
        if (userSubRecord != null){
            //判断订阅记录是否 已过期或者日期已被清空
            if(Objects.equals(userSubRecord.getStatus(),1)){
                userSubRecord.setEffictTransferTime(userSubRecord.getEffictTransferTime() + hour.multiply(BigDecimal.valueOf(3600000L)).longValue());
            }else{
                userSubRecord.setEffictTransferTime(hour.multiply(BigDecimal.valueOf(3600000L)).longValue());
                userSubRecord.setStatus(1);
            }
            int subCount = this.update(userSubRecord);
            //发送邮件
            User user = userServiceImpl.selectUserById(userSubRecordDto.getUserId());
            if (user != null && StringUtils.isNotEmpty(user.getEmail())) {
                userSubRecord.setEffictHour(hour.toString());
                emailSendCodeServiceImpl.sendEmailSubscribe(userSubRecord, user, order, goods.getDesc());
            }
            if(subCount <= 0){
                log.error("订单状态更新失败,用户订阅记录更新失败,订单号:{}",order.getOrderNo());
                return ;
            }
        }else{
            userSubRecord = new UserSubRecord();
            userSubRecord.setUserId(userSubRecordDto.getUserId());
            User user = userServiceImpl.selectUserById(userSubRecordDto.getUserId());
            if(user != null){
                Device device = deviceServiceImpl.selectDeviceByUserId(user.getId());
                if (device == null){
                    log.warn("用户查询设备失败,用户ID:{}",userSubRecordDto.getUserId());
                }else{
                    userSubRecord.setDeviceId(device.getId());
                }
            }
            GoodsType goodsType = goodsTypeServiceImpl.selectGoodsTypeById(userSubRecordDto.getGoodsTypeId());
            if(goodsType != null){
                userSubRecord.setGoodsTypeName(goodsType.getName());
            }
            userSubRecord.setGoodsTypeId(userSubRecordDto.getGoodsTypeId());
            userSubRecord.setProductId(userSubRecordDto.getProductId());
            userSubRecord.setProductName(userSubRecordDto.getProductName());
            userSubRecord.setEffictTransferTime(hour.multiply(BigDecimal.valueOf(3600000L)).longValue());
            userSubRecord.setStatus(1);
            int subCount = this.insert(userSubRecord);

            //发送邮件
            if (user != null && StringUtils.isNotEmpty(user.getEmail())) {
                userSubRecord.setEffictHour(hour.toString());
                emailSendCodeServiceImpl.sendEmailSubscribe(userSubRecord, user, order, goods.getDesc());
            }

            if(subCount <= 0){
                log.error("订单状态更新失败,用户订阅记录新增失败,订单号:{}",order.getOrderNo());
                return ;
            }
        }
    }
}
